package org.meb.conquest.ui;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;

import org.codehaus.jackson.JsonProcessingException;
import org.meb.conquest.rest.json.CardLoader;
import org.meb.conquest.rest.json.CardSetLoader;
import org.meb.conquest.rest.json.JsonUtils;
import org.meb.conquest.rest.json.model.JsonCard;
import org.meb.conquest.rest.json.model.JsonCardSet;
import org.meb.conquest.rest.json.model.JsonDomain;

@SessionScoped
public class JsonStaticCache implements Serializable {

	private static final long serialVersionUID = 7126894784914993695L;

	public enum Type {
		CARDS, CARD_SETS, DOMAIN
	};

	@Inject
	private CardLoader cardLoader;

	@Inject
	private CardSetLoader cardSetLoader;

	private Map<String, Map<Type, Object>> cache;

	public JsonStaticCache() {
		cache = new HashMap<>();
		cache.put("en", new HashMap<Type, Object>());
		cache.put("pl", new HashMap<Type, Object>());
	}

	@SuppressWarnings("unchecked")
	public List<JsonCard> getCards(String language) {
		Type type = Type.CARDS;

		List<JsonCard> cards = (List<JsonCard>) cache.get(language).get(type);
		if (cards == null) {
			synchronized (this) {
				cards = (List<JsonCard>) cache.get(language).get(type);
				if (cards == null) {
					cards = cardLoader.loadCards();
					cache.get(language).put(type, cards);
				}
			}
		}

		return cards;
	}

	public String getCardsJson(String language) throws JsonProcessingException, IOException {
		return JsonUtils.write(getCards(language));
	}

	@SuppressWarnings("unchecked")
	public List<JsonCardSet> getCardSets(String language) {
		Type type = Type.CARD_SETS;

		List<JsonCardSet> sets = (List<JsonCardSet>) cache.get(language).get(type);
		if (sets == null) {
			synchronized (this) {
				sets = (List<JsonCardSet>) cache.get(language).get(type);
				if (sets == null) {
					sets = cardSetLoader.loadCardSets();
					cache.get(language).put(type, sets);
				}
			}
		}

		return sets;
	}

	public String getCardSetsJson(String language) throws JsonProcessingException, IOException {
		return JsonUtils.write(getCardSets(language));
	}
	
	@SuppressWarnings("unchecked")
	public List<JsonDomain> getDomains(String language) {
		Type type = Type.DOMAIN;

		List<JsonDomain> sets = (List<JsonDomain>) cache.get(language).get(type);
		if (sets == null) {
			synchronized (this) {
				sets = (List<JsonDomain>) cache.get(language).get(type);
				if (sets == null) {
//					sets = cardSetLoader.loadDomains();
//					cache.get(language).put(type, sets);
				}
			}
		}

		return sets;
	}

	public String getDomainsJson(String language) throws JsonProcessingException, IOException {
		return JsonUtils.write(getDomains(language));
	}
}
